



#include "..\Headers\BC_Entity.h"



// static member initialization :

LPDIRECT3DDEVICE9 BCEntity::dxDevice = NULL;
LPDIRECT3DTEXTURE9 BCEntity::textureAtlas = NULL;


BCEntity::BCEntity(const BCVector2d& pos , eEntityType type  , float speed , float damage , float animationSpeed , float energy):
	sprite(NULL),
	moveSpeed(speed),
	damage(damage),
	animationSpeed(animationSpeed),
	energy(energy),
	scale(1.0f),
	rotation(0.0f),
	animationPlaying(false),
	currentFrameSetId(0),
	currentFrameTime(0.0f),
	currentFrameSet(NULL),
	frameCounter(0),
	position(pos)

{
	entityType = type;

	bool condition = SUCCEEDED(D3DXCreateSprite(dxDevice,&sprite));
	BC_CHECK_ERROR(condition , "Failed to create sprite")
	
	rec.left = 0;
	rec.top = 0;
	rec.right = 15;
	rec.bottom = 15;

}



BCEntity::~BCEntity()
{
	sprite->Release();
}




void BCEntity::init(LPDIRECT3DDEVICE9 device , LPDIRECT3DTEXTURE9 texture)
{
	dxDevice = device;
	textureAtlas = texture;
}


void BCEntity::setAnimationSpeed(float speed)
{
	animationSpeed = speed;	
}


void BCEntity::setPosition(const BCVector2d &pos)
{
	oldPosition = position;
	position = pos;
}


void BCEntity::moveDown()
{
	setRotation(180);
	oldPosition = position;
	position.y += moveSpeed;
}


void BCEntity::moveLeft()
{
	setRotation(270);
	oldPosition = position;
	position.x -= moveSpeed;
}


void BCEntity::moveRight()
{
	setRotation(90);
	oldPosition = position;
	position.x += moveSpeed;
}


void BCEntity::moveUp()
{
	setRotation(0);
	oldPosition = position;
	position.y -= moveSpeed;
}





void BCEntity::createFrameSet(int frameSetId)
{
	sFrameSet frameData;
	frameData.frameSetId = frameSetId;
	animationFrames.push_back(frameData);
}


void BCEntity::playAnimation(int frameSetId)
{
	if (animationPlaying) return;
	// iterate trough our frame set list and find the frameset that we want to play

	for (std::list<sFrameSet>::iterator it = animationFrames.begin(); it != animationFrames.end(); it ++)
	{
		// if there is a frameset with this id : 
		if ((*it).frameSetId == frameSetId)
		{
			if (currentFrameSet ==  &*it) 
			{
				animationPlaying = true;
				return;
			}
			// store the pointer to our frameset data...
			currentFrameSet = &*it;
			animationPlaying = true;
			frameCounter = 0;

			return;
		}
	}
	// if the program gets to this line , it means we have no valid animation data... so set animation playing to false

	animationPlaying = false;
	currentFrameSet = NULL;
	
	rec.left = 0;
	rec.top = 0;
	rec.right = 15;
	rec.bottom = 15;
}



void BCEntity::stopAnimation()
{
	animationPlaying = false;
}




void BCEntity::addFrame(int frameSetId, int left, int top, int right, int bottom)
{

	for (std::list<sFrameSet>::iterator it = animationFrames.begin(); it != animationFrames.end(); it++)
	{
		if ((*it).frameSetId == frameSetId)
		{
			RECT rec;
			rec.left = left;
			rec.top = top;
			rec.right = right;
			rec.bottom = bottom;
			(*it).atlasCoordinates.push_back(rec);
		}
	}


}


void BCEntity::animate(float deltaTime)
{
	// if we have no animation sets , just return , do nothing

	if (animationFrames.size() == 0) 
	{
		rec.left = 0;
		rec.top = 0;
		rec.right = 15;
		rec.bottom = 15;
		return;
	}
	// if animation is playing :
	if (animationPlaying)
	{
		// calculate the time of our frame to display :
		currentFrameTime += animationSpeed * deltaTime;
		
		// if it's time for displaying a frame , lets do it ! :)
		if (currentFrameTime >= 1.0f)
		{
			// reset the timer :
			currentFrameTime = 0.0f;
			
			// if we have a valid frameset 
			if (currentFrameSet != NULL)
			{
				// if the frame we try to set isn't bigger than our actual buffer...
				if ((currentFrameSet->atlasCoordinates.size() > 0))
				{
					// thats cool about std::vector it has a [] operator , so we can easily access them as a simple array
					rec = currentFrameSet->atlasCoordinates[frameCounter];
					frameCounter ++;
					if (frameCounter >= currentFrameSet->atlasCoordinates.size()) frameCounter = 0;
				}

			}
		}
	}

}



bool BCEntity::update(float deltaTime)
{

	// update the animation :
	animate(deltaTime);

	// update the transform
	D3DXVECTOR2 center((rec.right - rec.left) /2.0f , (rec.bottom - rec.top) / 2.0f );
	D3DXVECTOR2 scaling(2,2);
	D3DXVECTOR2 pos = position.getD3DVector2();

	D3DXMatrixTransformation2D(&mat,&center,0.0,&scaling,&center,rotation,&pos);
	sprite->SetTransform(&mat);

	return true;
}


void BCEntity::draw()
{
	sprite->Begin(D3DXSPRITE_ALPHABLEND);
	sprite->Draw(textureAtlas,&rec,NULL,NULL,0xffffffff);
	sprite->End();
}




